package com.gitee.faster.webdav.logger;

import cn.hutool.core.util.ServiceLoaderUtil;
import com.gitee.faster.webdav.kernel.Configuration;
import org.slf4j.Marker;
import org.slf4j.event.Level;
import org.slf4j.helpers.LegacyAbstractLogger;

import java.io.Serial;
import java.util.List;

/**
 * 格式化日志模板并根据日志级别向控制台输出彩色日志信息
 *
 * @author hongda.li
 */
public class Logger extends LegacyAbstractLogger {
    @Serial
    private static final long serialVersionUID = -1L;

    private static List<LoggerProcessor> processorList;

    public Logger(String name) {
        this.name = name;
    }

    @Override
    protected String getFullyQualifiedCallerName() {
        return this.name;
    }

    @Override
    protected void handleNormalizedLoggingCall(Level level,
                                               Marker marker,
                                               String format,
                                               Object[] arguments,
                                               Throwable throwable) {
        // 未开启则跳过输出
        if (!this.isEnabled(level)) {
            return;
        }

        getProcessorList().forEach(processor -> {
            try {
                processor.process(this.getName(), level, format, throwable, arguments);
            } catch (Exception e) {
                e.printStackTrace(System.err);
            }
        });
    }

    private boolean isEnabled(Level level) {
        return Configuration.getInstance().getDefaultLevel().getValue() <= level.toInt();
    }

    @Override
    public boolean isTraceEnabled() {
        return this.isEnabled(Level.TRACE);
    }

    @Override
    public boolean isDebugEnabled() {
        return this.isEnabled(Level.DEBUG);
    }

    @Override
    public boolean isInfoEnabled() {
        return this.isEnabled(Level.INFO);
    }

    @Override
    public boolean isWarnEnabled() {
        return this.isEnabled(Level.WARN);
    }

    @Override
    public boolean isErrorEnabled() {
        return this.isEnabled(Level.ERROR);
    }

    private static List<LoggerProcessor> getProcessorList() {
        if (processorList != null) {
            return processorList;
        }
        synchronized (Logger.class) {
            if (processorList == null) {
                processorList = ServiceLoaderUtil.loadList(LoggerProcessor.class);
            }
        }
        return processorList;
    }
}
